﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using FU.Capstones.IMS.Services.Common;
using FU.Capstones.IMS.Services.Common.DataContracts;
using FU.Capstones.IMS.Services.Common.Respondents;
using FU.Capstones.IMS.Services.Interfaces;

namespace FU.Capstones.IMS.Services.DAOs
{
    public class RoleDAO : DAOBase, IRoleDAO
    {
        #region IRoleDAO Members

        public CollectionFeedback<Role> GetCollection(bool isShowAll)
        {
            var feedback = new CollectionFeedback<Role> {IsSuccessful = false};
            try
            {
                OpenConnection();

                var command = new SqlCommand("GetCollectionRole", imsConnection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@IsShowAll", isShowAll);

                SqlDataReader reader = command.ExecuteReader();

                var roles = new List<Role>();
                while (reader.Read())
                {
                    var role = new Role();

                    role.RoleID = Convert.ToInt32(reader["RoleID"]);
                    role.RoleCode = Convert.ToString(reader["RoleCode"]);
                    role.RoleName = Convert.ToString(reader["RoleName"]);
                    role.BriefDescription = Convert.ToString(reader["BriefDescription"]);
                    role.FullDescription = Convert.ToString(reader["FullDescription"]);
                    role.IsDelete = Convert.ToBoolean(reader["IsDelete"]);
                    role.AuthorizationCollection = new List<int>();

                    string stemp = Convert.ToString(reader["AuthorizationIDs"]);
                    if (!string.IsNullOrEmpty(stemp))
                    {
                        string[] authorizationIDs = stemp.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);

                        foreach (string authorizationID in authorizationIDs)
                        {
                            if (!string.IsNullOrEmpty(authorizationID))
                            {
                                role.AuthorizationCollection.Add(Convert.ToInt32(authorizationID));
                            }
                        }
                    }
                    roles.Add(role);
                }

                feedback.Message = InventoryConstants.Messages.GetSuccessfully;
                feedback.IsSuccessful = true;
                feedback.Data = roles;

                //Log.Info("GetRoleCollection: {0}", DateTime.Now);
            }
            catch (SqlException se)
            {
                //Log.Error("GetRoleCollection - SqlException: {0} - {1}", se.StackTrace, DateTime.Now);
                feedback.Message = se.Message;
                feedback.IsSuccessful = false;
            }
            catch (Exception e)
            {
                //Log.Error("GetRoleCollection - Exception: {0} - {1}",e.StackTrace, DateTime.Now);
                feedback.Message = e.Message;
                feedback.IsSuccessful = false;
            }
            finally
            {
                CloseConnection();
            }
            return feedback;
        }

        public CollectionFeedback<Role> GetCollectionType(bool isShowAll)
        {
            var feedback = new CollectionFeedback<Role> {IsSuccessful = false};
            try
            {
                OpenConnection();

                var command = new SqlCommand("GetCollectionRole", imsConnection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@IsShowAll", isShowAll);

                SqlDataReader reader = command.ExecuteReader();

                var roles = new List<Role>();
                while (reader.Read())
                {
                    var role = new Role();

                    role.RoleID = Convert.ToInt32(reader["RoleID"]);
                    role.RoleCode = Convert.ToString(reader["RoleCode"]);
                    role.RoleName = Convert.ToString(reader["RoleName"]);
                    role.BriefDescription = Convert.ToString(reader["BriefDescription"]);
                    role.FullDescription = Convert.ToString(reader["FullDescription"]);
                    role.IsDelete = Convert.ToBoolean(reader["IsDelete"]);

                    roles.Add(role);
                }

                feedback.Message = InventoryConstants.Messages.GetSuccessfully;
                feedback.IsSuccessful = true;
                feedback.Data = roles;

                //Log.Info("GetRoleCollection: {0}", DateTime.Now);
            }
            catch (SqlException se)
            {
                //Log.Error("GetRoleCollection - SqlException: {0} - {1}", se.StackTrace, DateTime.Now);
                feedback.Message = se.Message;
                feedback.IsSuccessful = false;
            }
            catch (Exception e)
            {
                //Log.Error("GetRoleCollection - Exception: {0} - {1}",e.StackTrace, DateTime.Now);
                feedback.Message = e.Message;
                feedback.IsSuccessful = false;
            }
            finally
            {
                CloseConnection();
            }
            return feedback;
        }

        public SingleFeedback<Role> GetSingle(int objectID)
        {
            var feedback = new SingleFeedback<Role>
                               {IsSuccessful = false, Data = new Role {AuthorizationCollection = new List<int>()}};
            try
            {
                var command = new SqlCommand("GetSingleRole", imsConnection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@RoleID", objectID);

                OpenConnection();

                SqlDataReader reader = command.ExecuteReader();
                if (reader.HasRows && reader.Read())
                {
                    feedback.Data.RoleID = Convert.ToInt32(reader["RoleID"]);
                    feedback.Data.RoleCode = Convert.ToString(reader["RoleCode"]);
                    feedback.Data.RoleName = Convert.ToString(reader["RoleName"]);
                    feedback.Data.BriefDescription = Convert.ToString(reader["BriefDescription"]);
                    feedback.Data.IsDelete = Convert.ToBoolean(reader["IsDelete"]);
                    feedback.Data.FullDescription = Convert.ToString(reader["FullDescription"]);

                    if (reader.NextResult())
                    {
                        while (reader.Read())
                        {
                            feedback.Data.AuthorizationCollection.Add(Convert.ToInt32(reader["AuthorizationID"]));
                        }
                    }

                    feedback.Message = InventoryConstants.Messages.GetSuccessfully;
                    feedback.IsSuccessful = true;
                }
                else
                {
                    feedback.Message = InventoryConstants.Messages.GetFailed;
                    feedback.IsSuccessful = false;
                    feedback.Data = null;
                }

                Log.Info("GetSingleRole: {0} - {1}", objectID, DateTime.Now);
            }
            catch (SqlException se)
            {
                Log.Error("GetSingleRole - SqlException: {0} - {1}", se.StackTrace, DateTime.Now);
                feedback.Message = se.Message;
            }
            catch (Exception e)
            {
                Log.Error("GetSingleRole - Exception: {0} - {1}", e.StackTrace, DateTime.Now);
                feedback.Message = e.Message;
            }
            finally
            {
                CloseConnection();
            }
            return feedback;
        }

        public SingleFeedback<int> Insert(Role data)
        {
            var feedback = new SingleFeedback<int> {IsSuccessful = false};
            try
            {
                var command = new SqlCommand("InsertRole", imsConnection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@RoleCode", data.RoleCode);
                command.Parameters.AddWithValue("@RoleName", data.RoleName);
                command.Parameters.AddWithValue("@BriefDescription", data.BriefDescription);
                command.Parameters.AddWithValue("@FullDescription", data.FullDescription);
                command.Parameters.AddWithValue("@AuthorizationIDList", GetIDString(data.AuthorizationCollection));

                command.Parameters.Add("@RoleID", SqlDbType.Int);
                command.Parameters["@RoleID"].Direction = ParameterDirection.Output;

                OpenConnection();
                command.ExecuteNonQuery();

                int temp = Convert.ToInt32(command.Parameters["@RoleID"].Value);
                if (temp > 0)
                {
                    feedback.Message = InventoryConstants.Messages.InsertSuccessfully;
                    feedback.IsSuccessful = true;
                    feedback.Data = temp;
                }
                else
                {
                    feedback.Message = InventoryConstants.Messages.InsertFailed;
                }

                Log.Info("InsertRole: {0} - {1}", feedback.Data, DateTime.Now);
            }
            catch (SqlException se)
            {
                Log.Error("InsertRole - SqlException: {0} - {1}", se.StackTrace, DateTime.Now);
                feedback.Message = se.Message;
            }
            catch (Exception e)
            {
                Log.Error("InsertRole - Exception: {0} - {1}", e.StackTrace, DateTime.Now);
                feedback.Message = e.Message;
            }
            finally
            {
                CloseConnection();
            }
            return feedback;
        }

        public Feedback Update(Role data)
        {
            var feedback = new Feedback {IsSuccessful = false};
            try
            {
                var command = new SqlCommand("UpdateRole", imsConnection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@RoleID", data.RoleID);
                command.Parameters.AddWithValue("@RoleCode", data.RoleCode);
                command.Parameters.AddWithValue("@RoleName", data.RoleName);
                command.Parameters.AddWithValue("@BriefDescription", data.BriefDescription);
                command.Parameters.AddWithValue("@FullDescription", data.FullDescription);
                command.Parameters.AddWithValue("@AuthorizationIDList", GetIDString(data.AuthorizationCollection));
                //
                command.Parameters.Add(new SqlParameter
                                           {
                                               Direction = ParameterDirection.Output,
                                               ParameterName = "@Result",
                                               SqlDbType = SqlDbType.Bit
                                           });
                OpenConnection();
                command.ExecuteNonQuery();
                bool result = Convert.ToBoolean(command.Parameters["@Result"].Value);
                if (!result)
                {
                    feedback.Message = InventoryConstants.Messages.UpdateFailed;
                }
                else
                {
                    feedback.Message = InventoryConstants.Messages.UpdateSuccessfully;
                    feedback.IsSuccessful = true;
                }

                Log.Info("UpdateRole: {0} - {1} - {2}", data.RoleID, feedback.Message, DateTime.Now);
            }
            catch (SqlException se)
            {
                Log.Error("UpdateRole - SqlException: {0} - {1} - {2}", data.RoleID, se.StackTrace, DateTime.Now);
                feedback.Message = se.Message;
            }
            catch (Exception e)
            {
                Log.Error("UpdateRole - Exception: {0} - {1} - {2}", data.RoleID, e.StackTrace, DateTime.Now);
                feedback.Message = e.Message;
            }
            finally
            {
                CloseConnection();
            }
            return feedback;
        }

        public Feedback Delete(int objID)
        {
            var feedback = new Feedback {IsSuccessful = false};
            try
            {
                var command = new SqlCommand("DeleteRole", imsConnection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@RoleID", objID);

                OpenConnection();

                int rowCount = command.ExecuteNonQuery();
                if (rowCount == 1)
                {
                    feedback.Message = InventoryConstants.Messages.DeleteSuccessfully;
                    feedback.IsSuccessful = true;
                }
                else
                {
                    feedback.Message = InventoryConstants.Messages.DeleteFailed;
                    feedback.IsSuccessful = false;
                }

                Log.Info("DeleteRole: {0} - {1} - {2}", objID, feedback.Message, DateTime.Now);
            }
            catch (SqlException se)
            {
                Log.Error("DeleteRole - SqlException: {0} - {1} - {2}", objID, se.StackTrace, DateTime.Now);
                feedback.Message = se.Message;
            }
            catch (Exception e)
            {
                Log.Error("DeleteRole - Exception: {0} - {1} - {2}", objID, e.StackTrace, DateTime.Now);
                feedback.Message = e.Message;
            }
            finally
            {
                CloseConnection();
            }
            return feedback;
        }

        public CollectionFeedback<Role> Search(Role criteria)
        {
            var feedback = new CollectionFeedback<Role> {IsSuccessful = false};
            try
            {
                OpenConnection();

                var command = new SqlCommand("SearchRole", imsConnection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@RoleName",
                                                String.IsNullOrEmpty(criteria.RoleName)
                                                    ? criteria.RoleName
                                                    : criteria.RoleName.Trim());

                SqlDataReader reader = command.ExecuteReader();

                var roles = new List<Role>();

                while (reader.Read())
                {
                    var role = new Role();

                    role.RoleID = Convert.ToInt32(reader["RoleID"]);
                    role.RoleCode = Convert.ToString(reader["RoleCode"]);
                    role.RoleName = Convert.ToString(reader["RoleName"]);
                    role.BriefDescription = Convert.ToString(reader["BriefDescription"]);
                    role.FullDescription = Convert.ToString(reader["FullDescription"]);
                    role.IsDelete = Convert.ToBoolean(reader["IsDelete"]);

                    roles.Add(role);
                }

                feedback.Message = InventoryConstants.Messages.GetSuccessfully;
                feedback.IsSuccessful = true;
                feedback.Data = roles;

                //Log.Info("GetRoleCollection: {0}", DateTime.Now);
            }
            catch (SqlException se)
            {
                //Log.Error("GetRoleCollection - SqlException: {0} - {1}", se.StackTrace, DateTime.Now);
                feedback.Message = InventoryConstants.Messages.GetFailed;
                feedback.IsSuccessful = false;
            }
            catch (Exception e)
            {
                //Log.Error("GetRoleCollection - Exception: {0} - {1}",e.StackTrace, DateTime.Now);
                feedback.Message = InventoryConstants.Messages.GetFailed;
                feedback.IsSuccessful = false;
            }
            finally
            {
                CloseConnection();
            }
            return feedback;
        }

        public Feedback UndoDelete(int objID)
        {
            var feedback = new Feedback {IsSuccessful = false};
            try
            {
                var command = new SqlCommand("UndoDeletedRole", imsConnection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@RoleID", objID);

                OpenConnection();

                int rowCount = command.ExecuteNonQuery();
                if (rowCount == 1)
                {
                    feedback.Message = InventoryConstants.Messages.UndoDeleteSuccessfully;
                    feedback.IsSuccessful = true;
                }
                else
                {
                    feedback.Message = InventoryConstants.Messages.UndoDeleteFailed;
                    feedback.IsSuccessful = false;
                }

                Log.Info("UndoDeletedRole: {0} - {1} - {2}", objID, feedback.Message, DateTime.Now);
            }
            catch (SqlException se)
            {
                Log.Error("UndoDeletedRole - SqlException: {0} - {1} - {2}", objID, se.StackTrace, DateTime.Now);
                feedback.Message = se.Message;
            }
            catch (Exception e)
            {
                Log.Error("UndoDeletedRole - Exception: {0} - {1} - {2}", objID, e.StackTrace, DateTime.Now);
                feedback.Message = e.Message;
            }
            finally
            {
                CloseConnection();
            }
            return feedback;
        }

        #endregion
    }
}